package com.twang.stock.service.jinyan;

import com.google.common.collect.Lists;
import com.twang.stock.common.CommonUtils;
import com.twang.stock.enmu.CommonEnum;
import com.twang.stock.enmu.StockStatusEnum;
import com.twang.stock.entity.CompanyCodeInfo;
import com.twang.stock.entity.DuanXianBao;
import com.twang.stock.entity.StockInfo;
import com.twang.stock.mapper.CompanyCodeInfoMapper;
import com.twang.stock.mapper.DuanXianBaoMapper;
import com.twang.stock.mapper.StockInfoMapper;
import com.twang.stock.service.impl.MinutesVolRuleService;
import com.twang.stock.threadPool.AsycTaskExecutorConfig;
import com.twang.stock.utils.date.HolidayCopy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 短线选股
 */
@Service
public class DuanXianBaoXuanGuService {

    @Resource
    private StockInfoMapper stockInfoMapper;

    @Resource
    private CompanyCodeInfoMapper companyCodeInfoMapper;

    @Autowired
    private CommonService commonService;

    @Resource
    private DuanXianBaoMapper duanXianBaoMapper;

    @Autowired
    private AsycTaskExecutorConfig asycTaskExecutorConfig;

    @Autowired
    private MinutesVolRuleService minutesVolRuleService;

    @Autowired
    private StockInfoService stockInfoService;
    @Autowired
    private HolidayService holidayService;


    public void query(List<CompanyCodeInfo> bankuaiCodeList, List<CompanyCodeInfo> notbankuaiCodeList) {
        filterSubject(bankuaiCodeList, notbankuaiCodeList);
    }


    public List<DuanXianBao> queryHotStock(String date) {
        date = duanXianBaoMapper.getDate();
        DuanXianBao param = new DuanXianBao();
        param.setDate(date);
        List<DuanXianBao> records = duanXianBaoMapper.select(param);
        return records;
    }
    @Transactional(rollbackFor = Exception.class)
    public void filterSubject(List<CompanyCodeInfo> bankuaiCodeList, List<CompanyCodeInfo> notbankuaiCodeList) {
        List<CompanyCodeInfo> isTrueCodeInfoList = excuteRule();
        if(CollectionUtils.isEmpty(isTrueCodeInfoList)){
            return;
        }
        DuanXianBao record = new DuanXianBao();
        record.setDate(holidayService.getDayByNum(0));
        duanXianBaoMapper.delete(record);
        //判断是否在热点上
        List<String> bankuaiList = commonService.getbankuiStock(Lists.newArrayList());
        //过滤list
        bankuaiCodeList = isTrueCodeInfoList.stream().filter(item -> bankuaiList.contains(item.getCompanyCode())).collect(Collectors.toList());
        initDuanXianList(bankuaiCodeList, CommonUtils.DUAN_XIAN_BAO_TYPE_HOT,CommonUtils.DUAN_XIAN_BAO_RULE_1);
        notbankuaiCodeList = isTrueCodeInfoList.stream().filter(item -> !bankuaiList.contains(item.getCompanyCode())).collect(Collectors.toList());
        initDuanXianList(notbankuaiCodeList, CommonUtils.DUAN_XIAN_BAO_TYPE,CommonUtils.DUAN_XIAN_BAO_RULE_1);
        //生成题材
        initSubjectData(bankuaiList);
        //自主-突破5日线
        coreRule();
        //生成情绪高度指数 回填板块
    }

    /**
     * 查询突破
     */
    private void coreRule() {
        Example example=new Example(CompanyCodeInfo.class);
      Example.Criteria criteria= example.createCriteria();
        criteria.andEqualTo("strongRise",1);
        criteria.andEqualTo("strongRiseVol",1);
        criteria.andGreaterThanOrEqualTo("weight",5000);
        List<String> str=new ArrayList<>();
        str.add("强势下跌");
        str.add("震荡下跌");
        criteria.andNotIn("trendTypeName",str);
        List<CompanyCodeInfo> resultList = companyCodeInfoMapper.selectByExample(example);;
        example.orderBy("strongRise").desc();
        initDuanXianList(resultList, CommonUtils.DUAN_XIAN_BAO_TYPE, CommonUtils.DUAN_XIAN_BAO_RULE_2);
    }

    /**
     * 板块决策
     * @param bankuaiList
     */
    private void initSubjectData(List<String> bankuaiList) {
        List<CompanyCodeInfo> subjectList = Lists.newArrayList();
        bankuaiList.forEach(item -> {
            Example example = new Example(CompanyCodeInfo.class);
            example.createCriteria().andEqualTo("companyCode", item);
            List<CompanyCodeInfo> companyCodeInfoList = companyCodeInfoMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(companyCodeInfoList)) {
                CompanyCodeInfo companyCodeInfo = companyCodeInfoList.get(0);
                if (null != companyCodeInfo.getStrongRise() && null != companyCodeInfo.getStrongRiseVol() && null != companyCodeInfo.getWeight()) {
                    if (companyCodeInfo.getStrongRise() >=1 &&
                            companyCodeInfo.getWeight().compareTo(new BigDecimal(commonService.getValue(CommonEnum.HOT_TAG_STRONG_RIZE.getCode()))) >=0) {
                        subjectList.add(companyCodeInfo);
                    }
                }
            }
        });
        initDuanXianList(subjectList, CommonUtils.DUAN_XIAN_BAO_TYPE_HOT, CommonUtils.DUAN_XIAN_BAO_RULE_HOT_TAG);
    }

    private void initDuanXianList(List<CompanyCodeInfo> list, String type,String rule) {
        list.forEach(item -> {
            DuanXianBao duanXianBao = new DuanXianBao();
            duanXianBao.setStockCode(item.getCompanyCode());
            duanXianBao.setStockName(item.getShortName());
            duanXianBao.setStockId(item.getId());
            duanXianBao.setDate(HolidayCopy.getRealToday());
            duanXianBao.setType(type);
            duanXianBao.setCreateTime(new Date());
            duanXianBao.setModifyTime(new Date());
            duanXianBao.setPolicyDecision(item.getBuyOrSell());
            duanXianBao.setWeight(item.getWeight());
            duanXianBao.setStrongRise(item.getStrongRise());
            duanXianBao.setStrongRiseVol(item.getStrongRiseVol());
            duanXianBao.setRule(rule);
            asycTaskExecutorConfig.taskQueueExecutor().execute(() -> duanXianBaoMapper.insert(duanXianBao));
        });
    }

    /**
     * @return
     */
    public List<CompanyCodeInfo> excuteRule() {
        Example example = new Example(CompanyCodeInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("buyOrSell", StockStatusEnum.BUY.getMessage());
        criteria.andEqualTo("strongRise", 1);
        criteria.andGreaterThan("tradingVolume",5);
        example.orderBy("strongRiseVol").desc();
        List<CompanyCodeInfo> companyCodeInfoList = companyCodeInfoMapper.selectByExample(example);
        List<CompanyCodeInfo> isTrueCodeInfoList = Lists.newArrayList();
        companyCodeInfoList.forEach(item -> {
            //需要判断放量的几天里面，最大的量能是不是绿柱，是的话 ，排除
            //if (isGreenVol(item.getCompanyCode(), item.getStrongRiseVol())) {
            if (getPrice(item.getCompanyCode())) {
                isTrueCodeInfoList.add(item);
            }
        });
        return isTrueCodeInfoList;
    }

    public Boolean getPrice(String code) {
        StockInfo record = stockInfoService.getLastData(code);
        if (null != record && record.getZhangdie().compareTo(BigDecimal.ZERO) == 1) {
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }

    /**
     * 判断量能是不是绿柱子
     */
    public Boolean isGreenVol(String code, Integer num) {
        List<StockInfo> stockInfoList = stockInfoMapper.selectByLIimitNum(code, num);
        StockInfo maxVolStockCode = stockInfoList.stream().max(Comparator.comparing(item -> item.getVolMay1())).get();
        return zhangOrDie(maxVolStockCode);
    }

    private Boolean zhangOrDie(StockInfo info) {
        updateHznagDie(info);
        if (info.getZhangdie().compareTo(BigDecimal.ZERO) == 1) {
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }

    private void updateHznagDie(StockInfo item) {
        //上一交易日
        StockInfo stockInfoYesterDay = minutesVolRuleService.getCode(item.getCode(), item.getDate());
        if (null == stockInfoYesterDay) {
            return;
        }
        item.setZhangdie(((item.getPrice().subtract(stockInfoYesterDay.getPrice())).divide(stockInfoYesterDay.getPrice(), 5, BigDecimal.ROUND_HALF_UP)).multiply(new BigDecimal(100)));
        stockInfoMapper.updateByPrimaryKey(item);
    }
}
